home *** CD-ROM | disk | FTP | other *** search
- /*
- * beep.c - adds a sampled sound to DisplayBeep()
- *
- * Bruno Costa - 19 Feb 91 - 19 Feb 91
- *
- * NOTE:
- * This program is VERY sensitive to compiler environment.
- * Compile under Lattice 5.1 with options -r0 -y -v.
- */
-
- /*
- * TODO: add option to remove screen flash
- */
-
- #include <exec/types.h>
- #include <intuition/intuition.h>
- #include <graphics/gfxmacros.h>
- #include <proto/exec.h>
- #include <proto/dos.h>
- #include <proto/intuition.h>
-
- #include "intuition.lvo"
-
- #define MAX(a,b) (((a)>(b))?(a):(b))
- #define MIN(a,b) (((a)<(b))?(a):(b))
-
- #define PORTNAME "beep.port"
- #define INVALID (-1)
-
- #if DETACH
- long _stack = 3000;
- char *_procname = "BeepHandler";
- long _priority = 2;
- long _BackGroundIO = 1;
- extern BPTR _Backstdout;
- #else
- BPTR _Backstdout;
- #endif
-
- /*
- * Resident Amiga libraries
- */
- struct Library *IntuitionBase;
-
- /*
- * CLI Messages
- */
- #define BANNER "\x1b[33mBeep 1.0\x1b[31m - \xa9 1991 by Bruno Costa\n"
- #define USAGE "usage: \x1b[1mBeep\x1b[0m [-q | <soundfile>]\n"
- #define REMOVING "\x1b[1mBeep:\x1b[0m handler removed.\n"
- #define NOTLOAD "\x1b[1mBeep:\x1b[0m could not load desired sound.\n"
-
- /*
- * pointer to old system functions
- */
- typedef void (* __asm BeepFunc) (register __a0 struct Screen *scr,
- register __a6 struct Library *ibase);
-
- static BeepFunc oldbeep;
-
- /*
- * Data shared by handler and interposed function
- */
- static struct Task *handler = NULL;
- ULONG beepsig = 0;
- int flash = TRUE;
-
- /*
- * C routine to be interposed
- */
- void __asm mybeep (register __a0 struct Screen *scr,
- register __a6 struct Library *ibase)
- {
- Signal (handler, 1L << beepsig);
- if (flash)
- (*oldbeep) (scr,ibase);
- }
-
-
- /*
- * message port
- */
- static struct MsgPort myport;
-
-
- void usage (void) /* dead end */
- {
- Write (_Backstdout, USAGE, sizeof(USAGE));
- #if DETACH
- Close (_Backstdout);
- #endif
- exit (5);
- }
-
-
- void main (int argc, char *argv[])
- {
- char *soundfile = NULL;
- int removed, stay = FALSE;
- struct MsgPort *port;
-
- #if !DETACH
- _Backstdout = Output();
- #endif
-
- port = FindPort (PORTNAME);
- if (!port)
- {
- port = &myport;
- stay = TRUE;
- }
-
- if (_Backstdout && argc)
- {
- if (stay)
- Write (_Backstdout, BANNER, sizeof(BANNER));
-
- if (argc > 2)
- usage ();
- else if (argc == 2)
- if (argv[1][0] == '-' && argv[1][1] == 'q')
- {
- if (stay)
- stay = FALSE;
- else
- {
- Signal (port->mp_SigTask, 1L << port->mp_SigBit);
- port = &myport;
- }
- Write (_Backstdout, REMOVING, sizeof(REMOVING));
- }
- else
- soundfile = argv[1];
-
- if (stay)
- {
- if (!soundfile)
- usage ();
- if (!load (soundfile))
- {
- Write (_Backstdout, NOTLOAD, sizeof(NOTLOAD));
- soundfile = NULL;
- }
- }
-
- #if DETACH
- Close (_Backstdout);
- #endif
- }
-
- if (stay && soundfile)
- {
- /* create port */
- myport.mp_Node.ln_Name = PORTNAME;
- myport.mp_Node.ln_Pri = 0;
- myport.mp_Node.ln_Type = NT_MSGPORT;
- myport.mp_Flags = PA_SIGNAL;
- myport.mp_SigBit = AllocSignal (-1);
- myport.mp_SigTask = FindTask (NULL);
- AddPort (&myport);
- port = &myport;
- }
- else
- goto final;
-
- IntuitionBase = OpenLibrary ("intuition.library", 0);
-
- handler = FindTask (NULL);
- beepsig = AllocSignal (-1);
-
- Forbid ();
- oldbeep = SetFunction (IntuitionBase, _LVODisplayBeep, mybeep);
- Permit ();
-
- removed = FALSE;
- do
- {
- ULONG sigmask = Wait ((1L << port->mp_SigBit)|
- (SIGBREAKF_CTRL_C) |
- (1L << beepsig) );
-
- if (sigmask & (1L << beepsig))
- {
- #if DEBUG
- printf ("beeep!!!\n");
- #endif
- play ();
- }
-
- if (sigmask & (1L << port->mp_SigBit) || sigmask & SIGBREAKF_CTRL_C)
- {
- Forbid ();
- {
- BeepFunc pbeep = SetFunction (IntuitionBase, _LVODisplayBeep, oldbeep);
-
- if (pbeep != mybeep)
- {
- /*
- * Someone has interposed a handler after me. My handler can't be
- * removed: otherwise the system will crash after the other handler
- * removes itself.
- */
- (void) SetFunction (IntuitionBase, _LVODisplayBeep, pbeep);
- }
- else
- removed = TRUE;
- }
- Permit();
- }
- } while (!removed);
-
- FreeSignal (beepsig);
-
- CloseLibrary (IntuitionBase);
-
- /* Delete port */
- RemPort (port);
- FreeSignal (port->mp_SigBit);
-
- unload ();
-
- final:
- exit (0);
- }
-